<?php
namespace Payment\Common\Unionpay;

use Payment\Common\UnionpayConfig;
use Payment\Common\BaseData;
use Payment\Common\BaseStrategy;
use Payment\Common\PayException;
use Payment\Utils\ArrayUtil;


abstract class UnionpayBaseStrategy implements BaseStrategy
{
    /**
     * 银联配置文件
     * @var UnionpayConfig $config
     */
    protected $config;

    /**
     * 支付数据
     * @var BaseData $reqData
     */
    protected $reqData;

    /**
     * @var \AcpService
     */
    public $workService;
    /**
     * AliCharge constructor.
     * @param array $config
     * @throws PayException
     */
    public function __construct(array $config)
    {
        /* 设置内部字符编码为 UTF-8 */
        mb_internal_encoding("UTF-8");
        try {
            $this->config = new UnionpayConfig($config);
        } catch (PayException $e) {
            throw $e;
        }
    }

    /**
     * 获取支付对应的数据完成类
     * @return BaseData
     * @author helei
     */
    abstract protected function getBuildDataClass();

    public function handle(array $data)
    {
        $buildClass = $this->getBuildDataClass();

        try {
            $this->reqData = new $buildClass($this->config, $data);
        } catch (PayException $e) {
            throw $e;
        }

        $this->reqData->setSign();

        $data = $this->reqData->getData();

        $data = ArrayUtil::removeKeys($data, ['sign', 'sign_type']);

        return $this->retData($data);
    }

    /**
     * 处理银联的返回值并返回给客户端
     * @param array $data
     * @return string|array
     * @author helei
     */
    protected function retData(array $data)
    {
        $service = UnionpayConfig::$workService;
        if($data['channelType'] == '07'){
            // PC支付
            $url = $this->config->webGatewayUrl;
            $html_form = $service::createAutoFormHtml( $data, $url );

            return $html_form;
        }else if($data['channelType'] == '08'){
            // 手机支付
            $url = $this->config->appGatewayUrl;
            $ret = $service::post( $data, $url );

            $check_sign =  $service::validate ($ret);
            if($check_sign && $ret["respCode"] == "00"){
                return $ret;
            }
        }
        return null;
    }
}